package cn.tpshion.vm.service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.tpshion.vm.base.config.AuthConfig;
import cn.tpshion.vm.common.constant.UserStatus;
import cn.tpshion.vm.common.utils.AssertUtil;
import cn.tpshion.vm.common.utils.DateUtil;
import cn.tpshion.vm.domain.dto.auth.LoginDTO;
import cn.tpshion.vm.domain.dto.user.AddUserDTO;
import cn.tpshion.vm.domain.entity.User;
import cn.tpshion.vm.domain.entity.table.UserTableDef;
import cn.tpshion.vm.domain.vo.UserVO;
import cn.tpshion.vm.mapper.UserMapper;
import cn.tpshion.vm.service.UserService;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.util.List;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private AuthConfig authConfig;

    @Override
    public List<UserVO> getUserList() {
        List<User> list = userMapper.selectAll();
        if(ObjectUtils.isEmpty(list)){
            return List.of();
        }
        return list.stream().map(i -> {
            UserVO userVO = new UserVO();
            userVO.setId(i.getId());
            userVO.setUsername(i.getUsername());
            userVO.setStatus(i.getStatus());
            userVO.setUpdateTime(i.getUpdateTime());
            userVO.setCreateTime(i.getCreateTime());
            return userVO;
        }).toList();
    }

    @Override
    public void initBaseUser() {
        long count = userMapper.selectCountByQuery(new QueryWrapper());
        if(count > 0){
            return;
        }

        handleAddUser(authConfig.getUsername(), authConfig.getPassword());
        log.info("initBaseUser success username:{} password:{}", authConfig.getUsername(), authConfig.getPassword());
    }

    @Override
    public void checkUser(LoginDTO dto) {
        QueryWrapper queryWrapper = QueryWrapper.create().where(UserTableDef.USER.USERNAME.eq(dto.getUsername()));
        User user = userMapper.selectOneByQuery(queryWrapper);
        AssertUtil.isEmpty(user, "用户名或密码错误");
        AssertUtil.isTrue(UserStatus.DOWN.getStatus().equals(user.getStatus()), "用户已被禁用");
        AssertUtil.isFalse(BCrypt.checkpw(dto.getPassword(), user.getPassword()), "用户名或密码错误");
    }

    @Override
    public void addUser(AddUserDTO dto) {
        handleAddUser(dto.getUsername(), dto.getPassword());
    }

    private void handleAddUser(String username, String password){
        User user = new User();
        user.setUsername(username);
        user.setPassword(BCrypt.hashpw(password, BCrypt.gensalt()));
        user.setStatus(UserStatus.NORMAL.getStatus());
        user.setUpdateTime(DateUtil.now());
        user.setCreateTime(DateUtil.now());
        userMapper.insertSelective(user);
    }
}
